/**
* @file drv_cstxx.c
* @brief  ctp driver
* @details 
* @author huangbin
* @version V1.0.0
* @date 2025-05-10
* @copyright All documents are copyrighted by Shenzhen Xinlongwei Technology Co., LTD.
*            They may not be used for commercial purposes without permission
*/
#include "inc.h"



////////////////////////////////////////////////////
static int tp_reg_write(uint8_t reg_addr, uint8_t *reg_data, uint8_t cnt)
{
	int iError = 0;
	int i;
	
	I2c_Start();
	I2c_WriteByte(TP_IIC_SLAVE_ADDR);
	I2c_WriteByte(reg_addr);
	for ( i = 0; i < cnt; i++ )
	{
		I2c_WriteByte(reg_data[i]);
	}
	I2c_Stop();
	
	return iError;
}
static int tp_reg_read(uint8_t reg_addr, uint8_t *reg_data, uint8_t cnt)
{
	int iError = 0;
	int i;
	I2C_ACK_STATUS ack;
	I2C_ACK_STATUS sendAck = I2C_ACK;
	
	I2c_Start();
	ack = I2c_WriteByte(TP_IIC_SLAVE_ADDR);  //write
	if ( ack != I2C_ACK )
	{
		iError = -1;
	}
	ack = I2c_WriteByte(reg_addr);
	if ( ack != I2C_ACK )
	{
		iError = -1;
	}
	I2c_Stop(); // necessary
	I2c_Start();
	ack = I2c_WriteByte(TP_IIC_SLAVE_ADDR|0x01); //read
	if ( ack != I2C_ACK )
	{
		iError = -1;
	}
	for ( i = 0; i < cnt; i++ )
	{
		if ( i == cnt-1){
			sendAck = I2C_NAK;
		}
		reg_data[i] = I2c_ReadByte(sendAck);
	}
	I2c_Stop();
	return iError;
}
/////////////////////////////////// api ///////////////////////////////////////
Mouse_Typedef MouseData;
/*
chip id:
CST716 : 0x20
CST816S : 0xB4
CST816T : 0xB5
CST816D : 0xB6
*/
uint8_t tp_Cstxx_get_ChipId(void)
{
	uint8_t id,version;
#if CTP_TYPE == CTP_TYPE_CST816    
	tp_reg_read(0xA7,&id,1);
	tp_reg_read(0xA9,&version,1);
#elif   CTP_TYPE == CTP_TYPE_FT6336U    
	tp_reg_read(0xA6,&id,1);  //ft
	tp_reg_read(0xA8,&version,1);
#elif   CTP_TYPE == TP_IIC_SLAVE_ADDR_CST328    
	tp_reg_read(0xA7,&id,1); //cst
	tp_reg_read(0xA9,&version,1);
#endif
	DebugPrintf("tp chip id = 0x%02X,version=0x%02X\r\n",id,version);   
	return id;
}
//cst816d:报点速率10ms中断（下降沿中断,脉宽1.27ms)
//200k速率，读7个寄存器约需要545us
uint32_t tp_Cstxx_get_data(void)
{
    uint16_t x, y;
	volatile uint8_t ges,finger_num;
    uint8_t buf[8];
	
	tp_reg_read(0,buf,7); 
	ges = buf[1];
	finger_num = buf[2];
	x = ((buf[3] & 0x0F) << 8) | buf[4];
	y = ((buf[5] & 0x0F) << 8) | buf[6];
	
	//r1=gesture id,r2=手指个数
	//r3(b0-3)r4=x,r5(b0-3)r6=y
//    tp_reg_read(TP_REG_GES,&ges,1);
//    tp_reg_read(TP_REG_X,&x,1);
//    tp_reg_read(TP_REG_Y,&y,1);
//	tp_reg_read(TP_REG_IS_TOUCH,&is_touch,1);
//	DebugPrintf("x = %d,y=%d,gesture=0x%02X,finger num = %d\r\n",x,y,ges,finger_num); 
	if(finger_num) //按下了
	{
		if(MouseData.Status == MOUSE_DOWN) //上一次也是按下
		{
			if((MouseData.x == x) && (MouseData.y == y)) //坐标没有移动
			{
				return 0;
			}
			//按下并且移动了
//			guiSendMessageEx(MSG_MOUSE_MOVE,SET_MOUSE_COOR(x,y));
            DebugPrintf("mouse move x= %d,y=%d\r\n",x,y);   
		}
		else //第一次按下
		{
//			guiSendMessageEx(MSG_MOUSE_DOWN,SET_MOUSE_COOR(x,y));
            DebugPrintf("mouse down x= %d,y=%d\r\n",x,y);   
		}
		MouseData.x = x;	
		MouseData.y = y;
		MouseData.Status = MOUSE_DOWN; //更新状态及坐标
	}
	else //弹起
	{
        DebugPrintf("mouse up x= %d,y=%d\r\n",x,y);   
//		guiSendMessageEx(MSG_MOUSE_UP,SET_MOUSE_COOR(x,y));
		MouseData.x = INVALID_COOR;	//防止下一次在同一个地方按下
		MouseData.y = INVALID_COOR;
		MouseData.Status = MOUSE_UP; //更新状态及坐标
	}
    return 0;
}
void tp_Cstxx_Init(void)
{
		MouseData.x = INVALID_COOR;
		MouseData.y = INVALID_COOR;
		MouseData.Gesture = 0;
		MouseData.Status = MOUSE_UP;
		tp_Cstxx_get_ChipId();
}

//中断初始化
void tp_IntInit(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef  EXTI_InitStructure;
	
	RCC_APB2PeriphClockCmd(TP_INT_PORT_CLK|RCC_APB2Periph_AFIO,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = TP_INT_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//下降沿触发中断
	GPIO_Init(TP_INT_PORT, &GPIO_InitStructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource7);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	EXTI_InitStructure.EXTI_Line=EXTI_Line7;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_Init(&EXTI_InitStructure);   
}
void EXTI9_5_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line7)==SET)
    {
        EXTI_ClearITPendingBit(EXTI_Line7);
        DebugPrintf("mouse press...\r\n");   
        tp_Cstxx_get_data();
    }
}
void tp_Reset(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd (TP_RESET_PORT_CLK,ENABLE);

	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_PP;

	GPIO_InitStructure.GPIO_Pin = TP_RESET_PIN;
	GPIO_Init (TP_RESET_PORT, & GPIO_InitStructure );

	TP_RESET_HIGH();
	HardWareDelay_ms(1);
	TP_RESET_LOW();
	HardWareDelay_ms(10);
	TP_RESET_HIGH();
	HardWareDelay_ms(60); //>50ms
}

void tp_Init(void)
{
    I2c_Init();
    tp_IntInit();
    tp_Cstxx_Init();
    tp_Reset();
}


















//////////////////////////////////////////////////////////



